<?php
/**
* @version		$Id: helper.php 10214 2008-04-19 08:59:04Z eddieajau $
* @package		Joomla
* @copyright	Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
* @license		GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/

/** ensure this file is being included by a parent file */
defined('_JEXEC') or die('Direct Access to this location is not allowed.');

class modImageFlowHelper
{
	function getTemplate( $tmplt )
	{
		jimport('joomla.filesystem.file');
		//
		//	load the template file
		//
		$tmpltspec = JPATH_BASE . DS . $tmplt;
		$tmpltspec = JPath::clean( $tmpltspec, DS );
		$tmpltspec = modImageFlowHelper::resolvePathVars( $tmpltspec );
		$tmpltext = '';

		if (JFile::exists($tmpltspec))
		{
			$tmpltspecs = JFile::read($tmpltspec);
			$tmpltspecs = str_replace( "\r\n", "\n", $tmpltspecs );
			$tmpltspecs = str_replace( "\r", "\n", $tmpltspecs);
			$tmpltlines = explode( "\n", $tmpltspecs );

			for ($i=0; $i<count($tmpltlines); $i++)
			{
				$tmpltline = JString::ltrim($tmpltlines[$i]);
				if (JString::substr( $tmpltline, 0, 2) != '//')
				{
					$tmpltext .= $tmpltline;
				}
			}
		}
		return $tmpltext;
	}

	function metadataVarExists( &$metadataDefsArray, $val )
	{
		$values = array_values( $metadataDefsArray );
		for ($i = 0; $i < count( $values ); $i++)
		{
			$arrvalu = explode( ',', $values[$i]);
			if (JString::strcasecmp( $arrvalu[0], "$".$val ) == 0)
			{
				return TRUE;
			}
		}
		return FALSE;
	}

	function isMetaDataVariableMatch( $imgline, &$match)
	{
		if ( preg_match( "/[@]([^ \t]+)([ \t])*=([ \t])*\"([^\"]+)\"/i", $imgline, $match ) > 0 )
		{
			$match[4] = htmlspecialchars( $match[4]);
			return true;
		}
		if ( preg_match( "/[@]([^ \t]+)([ \t])*=([ \t])*'([^']+)'/i", $imgline, $match ) > 0 )
		{
			$match[4] = htmlspecialchars( $match[4]);
			return true;
		}
		return false;
	}

	function isVariableMatch( $imgline, &$match)
	{
		if ( preg_match( "/[$]([^ \t]+)([ \t])*=([ \t])*\"([^\"]+)\"/i", $imgline, $match ) > 0 )
		{
			$match[4] = htmlspecialchars( $match[4]);
			return true;
		}
		if ( preg_match( "/[$]([^ \t]+)([ \t])*=([ \t])*'([^']+)'/i", $imgline, $match ) > 0 )
		{
			$match[4] = htmlspecialchars( $match[4]);
			return true;
		}
		return false;
	}

	function resolveVariables( &$imgline, &$varArray, &$metadataDefsArray, &$metadataVarArray  )
	{

		$match = array();

		if ( modImageflowHelper::isMetaDataVariableMatch( $imgline, $match ))
		{
			do
			{
				$metadataDefsArray[$match[1]] = $match[4];
				$imgline = str_replace( $match[0], '', $imgline);
			}
			while( modImageflowHelper::isMetaDataVariableMatch( $imgline, $match ));
		}

		if ( modImageflowHelper::isVariableMatch( $imgline, $match ))
		{
			do
			{
				if (modImageFlowHelper::metadataVarExists($metadataDefsArray, $match[1]))
				{
					$metadataVarArray[$match[1]] = $match[4];
				}
				else
				{
					modImageFlowHelper::substituteVariables( $match[4], $varArray );
					$varArray[$match[1]] = $match[4];
				}
				$imgline = str_replace( $match[0], '', $imgline);
			}
			while ( modImageflowHelper::isVariableMatch( $imgline, $match ));

			return FALSE;
		}

		return modImageFlowHelper::substituteVariables( $imgline, $varArray );
	}

	function resolveMetaDataVariables( &$image, &$metadataDefsArray, &$metadataVarArray, $varDefsArray = array() )
	{
		$imagename = JPATH_BASE . DS . $image['img'];
		$imagename = JPath::clean( $imagename, DS );
		$varArray = array();

		if (JFile::exists($imagename))
		{
			$size = getimagesize( $imagename, $info );
			$imgmetadata = array();
			if (isset($info['APP13']))
			{
				$app13 = iptcparse($info['APP13']);
				if (is_array( $app13 ))
				{
					foreach ( $app13 as $key => $valu)
					{
						$c = '';
						$iptcvalue = '';
						foreach ($valu as $v)
						{
							$iptcvalue .= $c.$v;
							$c = ',';
						}
						$iptc['IPTC'][$key] = $iptcvalue;
					}
					$imgmetadata = array_merge( $imgmetadata, $iptc );
				}
			}
			if (function_exists( "exif_imagetype" ) &&
				exif_imagetype($imagename) == IMAGETYPE_JPEG)
			{
				$metadata = exif_read_data( $imagename, 0, true );
				$imgmetadata = array_merge( $imgmetadata, $metadata );
			}
			foreach ($metadataDefsArray as $key => $metadatadef )
			{
				$metadefs = explode( ',', $metadatadef );
				$founddef = false;
				if (count($metadefs) > 1)
				{
					$metadatafld = JString::str_ireplace( "$", "", $metadefs[0] );
					for ($i = 1; $i < count($metadefs); $i++)
					{
						$metaflds = explode( '.', JString::trim($metadefs[$i]) );
						if ( count($metaflds) == 2
							&&isset( $imgmetadata[JString::trim($metaflds[0])][JString::trim($metaflds[1])])
							)
						{
							$founddef = true;
							$value = $imgmetadata[JString::trim($metaflds[0])][JString::trim($metaflds[1])];
							$value = modImageFlowHelper::convert_charset($value);
							$value = JString::str_ireplace( "\0", "", $value );
							$varArray[$key] = htmlspecialchars(addslashes(stripslashes($value)),ENT_COMPAT, "UTF-8");
							if (JString::substr( $metadatadef, 0, 1) == "$" && isset($metadataVarArray[strtolower($metadatafld)]))
							{
								$varArray[strtolower($metadatafld)] = $metadataVarArray[strtolower($metadatafld)];
								modImageFlowHelper::substituteVariables( $varArray[strtolower($metadatafld)], $varArray );
							}
							break;
						}
						else
						{
							if (count($metaflds) == 1 && JString::substr( $metaflds[0], 0, 1) == "$")
							{
								$var = JString::str_ireplace( "$", "", $metaflds[0] );
								if (isset( $image[$var]))
								{
									$varArray[$key] = $image[$var];
								}
								else
								{
									if (isset( $varDefsArray[$var]))
									{
										$varArray[$key] = $varDefsArray[$var];
									}
								}
								if (JString::substr( $metadatadef, 0, 1) == "$" && isset($metadataVarArray[strtolower($metadatafld)]))
								{
									$varArray[strtolower($metadatafld)] = $metadataVarArray[strtolower($metadatafld)];
									modImageFlowHelper::substituteVariables( $varArray[strtolower($metadatafld)], $varArray );
								}
								break;
							}
						}
					}
				}
			}
			foreach ($image as $key => $value)
			{
				modImageFlowHelper::substituteVariables( $image[$key], $varArray );
			}
			return TRUE;
		}
		return FALSE;
	}

	function substituteVariables( &$imgline, &$varArray )
	{
		foreach( $varArray as $key => $var)
		{
			$imgline = str_replace( '{'.$key.'}', $var, $imgline );
		}
		return TRUE;
	}

	function combineLines( $imgspecs )
	{
		$lines = explode( "\n", $imgspecs );
		$imgs = array();

		for ($i=0; $i<count($lines); $i++)
		{
			if (isset($line))
		 	{
				$line .= $lines[$i];
			}
			else
			{
				$line = $lines[$i];
			}
			$line = JString::rtrim( $line, " \t" );
			if (JString::substr( $line, -1) == "&")
			{
				$line = JString::substr( $line, 0, JString::strlen( $line ) - 1 );
			}
			else
			{
				$imgs[] = $line;
				unset( $line );
			}
		}
		if (isset($line))
		{
			$imgs[] = $line;
		}
		return $imgs;
	}

	function getFiles( $path, $depth, $order )
	{
		$files = JFolder::files( $path, '.', $depth, true );
		switch($order)
		{
			case "0":
				// filename, ascending
				break;
			case "1":
				// filename decending
				rsort( $files );
				break;
			case "2":
				// modification time ascending
				$arr = array();
				foreach ($files as $file)
				{
					$arr[filemtime($file).$file] = $file;
				}
				ksort( $arr );
				return $arr;
				break;
			case "3":
				// modification time descending
				$arr = array();
				foreach ($files as $file)
				{
					$arr[filemtime($file).$file] = $file;
				}
				krsort($arr);
				return $arr;
				break;

		}
		return $files;
	}

	function getImages($params)
	{
		jimport('joomla.filesystem.file');
		$moduleid = $params->get('moduleid','imf');

		switch($params->get('loadfrom','0'))
		{
			case "0":
				$dirload = false;
				$listload = true;
				break;
			case "1":
				$dirload = true;
				$listload = false;
				break;
			case "2":
				$dirload = true;
				$listload = true;
				break;
		}

		$imglst = modImageFlowHelper::getImgFile( $params );
		if ($dirload)
		{
			$dirlst = modImageFlowHelper::getDirPath( $params );
		}

		$ndx = 0;
		if ($listload && $imglst != '')
		{
			$imgspec = JPATH_BASE . DS . $imglst;
			$imgspec = JPath::clean( $imgspec, DS );

			if (JFile::exists($imgspec))
			{
				$imgs = modImageFlowHelper::getSpecFile( $imgspec );
				$varArray = array();
				$metadataDefsArray = array();
				$metadataVarArray = array();

				for ($i=0; $i<count($imgs); $i++)
				{
					$imgline = JString::ltrim($imgs[$i]);
					if (JString::substr( $imgline, 0, 2) != '//' && modImageFlowHelper::resolveVariables( $imgline, $varArray, $metadataDefsArray, $metadataVarArray ) !== FALSE )
					{
						while ( preg_match( "/([ \t])*([A-Za-z0-9]*)([ \t])*=([ \t])*\"([^\"]+)\"/i", $imgline, $match ) > 0
							||preg_match( "/([ \t])*([A-Za-z0-9]*)([ \t])*=([ \t])*'([^']+)'/i", $imgline, $match ) > 0
							)
						{
							$img[JString::strtolower($match[2])] = addslashes(stripslashes($match[5]));
							$imgline = str_replace( $match[0], '', $imgline);
						}
						if (isset($img['img']))
						{
							$images[$ndx] = $img;
							$filename =	JFile::getName( JPath::clean( $images[$ndx]['img'] ));
							if ($params->get('stripext', 1 ) == 1)
							{
								$filename = JFile::stripExt( $filename );
							}
							$images[$ndx]['_filename'] = $filename;
							if ($params->get('ignoredupimages',0))
							{
								$dupcheck[JPath::clean( JURI::root(true). '/'. $images[$ndx]['img'], '/' )] = 1;
							}
							if (!isset($images[$ndx]['_id']))
							{
								$images[$ndx]['_id'] = $moduleid."_imageflow_image_".$ndx;
							}
							if (!isset($images[$ndx]['_group']))
							{
								$images[$ndx]['_group'] = $moduleid;
							}
							if (count($metadataDefsArray) > 0)
							{
								modImageFlowHelper::resolveMetaDataVariables( $images[$ndx], $metadataDefsArray, $metadataVarArray, $varArray );
							}
							$ndx++;
							unset($img);
						}
					}
				}
			}
		}

		if ($dirload && $dirlst != '')
		{
			$imgspec = JPATH_BASE . DS . $dirlst;
			$imgspec = JPath::clean( $imgspec, DS );

			if (JFolder::exists($imgspec))
			{
				$dirdepth = $params->get('dirdepth', 0 );
				$dirdepth = (is_numeric($dirdepth) ? (int)$dirdepth : 0 );
				$imgfiles = modImageFlowHelper::getFiles( $imgspec, $dirdepth, $params->get( 'imageorder', "0" ) );
				$limit = (int)$params->get('imagelimit', 0);
				if ($limit == 0)
				{
					$limit = count($imgfiles);
				}
				if ($limit > count($imgfiles))
				{
					$limit = count($imgfiles);
				}

				$metadataDefsArray = array();

				$tmpltspec = modImageFlowHelper::getDirMetaDataTmpl($params);

				if ($tmpltspec != '')
				{
					$tmpltspec = JPATH_BASE . DS . $tmpltspec;
					$tmpltspec = JPath::clean( $tmpltspec, DS );

					if (JFile::exists($tmpltspec))
					{
						$tmplt = modImageFlowHelper::getSpecFile( $tmpltspec );
						$varArray = array();
						$metadataVarArray = array();
						$tmpltVars = array();

						for ($i=0; $i<count($tmplt); $i++)
						{
							$tmpltline = JString::ltrim($tmplt[$i]);
							if (JString::substr( $tmpltline, 0, 2) != '//' && modImageFlowHelper::resolveVariables( $tmpltline, $varArray, $metadataDefsArray, $metadataVarArray ) !== FALSE )
							{
								while ( preg_match( "/([ \t])*([A-Za-z0-9]*)([ \t])*=([ \t])*\"([^\"]+)\"/i", $tmpltline, $match ) > 0
									||preg_match( "/([ \t])*([A-Za-z0-9]*)([ \t])*=([ \t])*'([^']+)'/i", $tmpltline, $match ) > 0
									)
								{
									$tmpltVars[JString::strtolower($match[2])] = $match[5];
									$tmpltline = str_replace( $match[0], '', $tmpltline);
								}
							}
						}
					}
				}
				$i = 0;
				$base = JPATH_BASE;
				$base = JPath::clean( $base );
				foreach($imgfiles as $pathfile)
				{
					$pathfile = JPath::clean( $pathfile );
					$filename = JFile::getName( $pathfile );
					$imgspec = JString::str_ireplace( $filename, '', $pathfile );
					if (JString::substr($imgspec, 0, JString::strlen($base)) == $base)
					{
						$imgspec = JString::substr( $imgspec, JString::strlen($base), JString::strlen($imgspec)-JString::strlen($base) );
					}
					$imgspec = JPath::clean( $imgspec, '/');
					$imgfile = $imgspec.$filename;
					if (preg_match("/\.jpg$|\.png$|\.gif$/i", $imgfile))
					{
						if (JString::substr( $filename, 0, 5) != 'refl_'
						&& $i < $limit
						&&!isset($dupcheck[JPath::clean( JURI::root(true). '/'. $imgfile, '/' )]))
						{
							if ($params->get('stripext',1) == 1)
							{
								$filename = JFile::stripExt( $filename );
							}
							$images[$ndx]['img'] = $imgfile;
							$images[$ndx]['imgalt'] = $filename;
							$images[$ndx]['imgtitle'] = $filename;
							$images[$ndx]['hreftitle'] = $filename;
							$images[$ndx]['caption'] = $filename;
							$images[$ndx]['_id'] = $moduleid."_imageflow_image_".$ndx;
							$images[$ndx]['_group'] = $moduleid;
							$images[$ndx]['_filename'] = $filename;
							$images[$ndx]['pathfile'] = $pathfile;
							$images[$ndx]['pathbase'] = JPATH_BASE;
							if (count($metadataDefsArray) > 0)
							{
								$images[$ndx] = array_merge( $images[$ndx], $tmpltVars );
								if (! modImageFlowHelper::resolveMetaDataVariables( $images[$ndx], $metadataDefsArray, $metadataVarArray, $varArray ))
								{
									$images[$ndx]['imgalt'] = $filename;
									$images[$ndx]['imgtitle'] = $filename;
									$images[$ndx]['hreftitle'] = $filename;
									$images[$ndx]['caption'] = $filename;
								}
							}
							$ndx++;
							$i++;
						}
					}
				}
			}
		}

		if (!isset($images) || count($images) == 0 )
		{
			$path_relative = str_replace(JPATH_BASE . DS, '', dirname(__FILE__) );
			$path_relative = JPath::clean( $path_relative, '/');
			$images[0]['img'] = $path_relative.'/images/qmark.jpg';
		}
		return $images;
	}

	function getDirMetaDataTmpl( $params )
	{
		$dirlst = $params->get('dirmetadatatemplate', 'modules/mod_imageflow/templates/metadatatemplate.txt');

		return modImageFlowHelper::resolvePathVars( $dirlst );
	}

	function getDirPath( $params )
	{
		$dirlst = $params->get('dirpath');

		return modImageFlowHelper::resolvePathVars( $dirlst );
	}

	function getImgFile( $params )
	{
		$filename = $params->get('imagelistfile');

		return modImageFlowHelper::resolvePathVars( $filename );
	}

	function resolvePathVars( $pathname )
	{
		$id = JRequest::GetInt( 'id' );
		$user = &JFactory::getUser();
		$username = $user->username;

		$path = JString::str_ireplace( "{username}", $username, $pathname );
		$path = JString::str_ireplace( "{id}", $id, $path );
		return $path;
	}

	function getSpecFile($filename)
	{
		$imgspecs = JFile::read($filename);
		$imgspecs = str_replace( "\r\n", "\n", $imgspecs );
		$imgspecs = str_replace( "\r", "\n", $imgspecs);
		$imgs = modImageFlowHelper::combineLines( $imgspecs );
		return $imgs;
	}

	function convert_charset($item)
	{
		if (function_exists( "mb_detect_encoding" ))
		{
			return modImageFlowHelper::fixEncoding($item);
		}

		if ($unserialize = unserialize($item))
		{
			foreach ($unserialize as $key => $value)
			{
				$unserialize[$key] = @iconv('windows-1256', 'UTF-8', $value);
			}
			$serialize = serialize($unserialize);
			return $serialize;
		}
		else
		{
			return @iconv('windows-1256', 'UTF-8', $item);
		}
	}

	function detect_cyr_charset($str)
	{
		if (!defined('IMAGEFLOW_LOWERCASE'))
		{
			define('IMAGEFLOW_LOWERCASE',3);
		}
		if (!defined('IMAGEFLOW_UPPERCASE'))
		{
			define('IMAGEFLOW_UPPERCASE',1);
		}
		$charsets = Array(
		                  'k' => 0,
		                  'w' => 0,
		                  'd' => 0,
		                  'i' => 0,
		                  'm' => 0
		                  );
		for ( $i = 0, $length = strlen($str); $i < $length; $i++ ) {
			$char = ord($str[$i]);
			//non-russian characters
			if ($char < 128 || $char > 256) continue;

			//CP866
			if (($char > 159 && $char < 176) || ($char > 223 && $char < 242))
				$charsets['d']+=IMAGEFLOW_LOWERCASE;
			if (($char > 127 && $char < 160)) $charsets['d']+=IMAGEFLOW_UPPERCASE;

			//KOI8-R
			if (($char > 191 && $char < 223)) $charsets['k']+=IMAGEFLOW_LOWERCASE;
			if (($char > 222 && $char < 256)) $charsets['k']+=IMAGEFLOW_UPPERCASE;

			//WIN-1251
			if ($char > 223 && $char < 256) $charsets['w']+=IMAGEFLOW_LOWERCASE;
			if ($char > 191 && $char < 224) $charsets['w']+=IMAGEFLOW_UPPERCASE;

			//MAC
			if ($char > 221 && $char < 255) $charsets['m']+=IMAGEFLOW_LOWERCASE;
			if ($char > 127 && $char < 160) $charsets['m']+=IMAGEFLOW_UPPERCASE;

			//ISO-8859-5
			if ($char > 207 && $char < 240) $charsets['i']+=IMAGEFLOW_LOWERCASE;
			if ($char > 175 && $char < 208) $charsets['i']+=IMAGEFLOW_UPPERCASE;

		}
		arsort($charsets);
		return key($charsets);
	}

	function fixEncoding($in_str)
	{
		$cur_encoding = mb_detect_encoding($in_str,mb_detect_order(),true);
		if ($cur_encoding === FALSE)
		{
			$cur_encoding = modImageFlowHelper::detect_cyr_charset($in_str);
			if ($cur_encoding == 'w')
			{
				return mb_convert_encoding( $in_str, 'UTF-8', 'windows-1251');
			}
			if ($cur_encoding == 'k')
			{
				return mb_convert_encoding( $in_str, 'UTF-8', 'koi8-r');
			}
			if ($cur_encoding == 'd')
			{
				return mb_convert_encoding( $in_str, 'UTF-8', 'cp866');
			}
			if ($cur_encoding == 'i')
			{
				return mb_convert_encoding( $in_str, 'UTF-8', 'iso-8859-5');
			}
			return utf8_encode($in_str);
		}
		if($cur_encoding == "UTF-8")
		{
			return $in_str;
		}
		return mb_convert_encoding( $in_str, 'UTF-8', $cur_encoding);
	}
}